home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr42 / vat041.zip / EXAMPLE.C < prev    next >
C/C++ Source or Header  |  1995-03-19  |  15KB  |  516 lines

  1.  
  2. /**************************************************************************
  3.   EXAMPLE.C
  4.  
  5.   Written by:  Eric Jorgensen (Feb, 1995)
  6.  
  7.   This code was written using Turbo C.  It is intended to demonstrate the
  8.   use of Varmint's Audio Tools and to provide a example code for program
  9.   who wish to use VAT.
  10.  
  11.                           This code is FREEWARE
  12.  
  13.   You are free to distribute without any restrictions as long as you
  14.   charge no fee.
  15.  
  16.  
  17. **************************************************************************/
  18.  
  19.  
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <conio.h>
  23. #include <dos.h>
  24. #include <io.h>
  25. #include <alloc.h>
  26. #include "sound.h"
  27. #include <math.h>
  28.  
  29.  
  30. #define getbit(x,y)  ((x>>y) & 0x01)
  31. #define setbit(x,y) x = x & (0x01<<y)
  32. #define togbit(x,y) x = x ^ (0x01<<y)
  33.  
  34.                                   // function prototypes
  35. void fmdemo(void);
  36. void mididemo(void);
  37. void sb_intro(void);
  38. void dspdemo(void);
  39.  
  40.  
  41. char    inst[9][11] =
  42.   {
  43.     { 0x03,0x01,0x00,0x00,0xF3,0xE4,0x64,0x35,0x00,0x01,0x00},  // Harpsichord
  44.     { 0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x06,0x03,0x00},  // intro voice
  45.     { 0x02,0x06,0x94,0x0A,0x80,0x80,0x00,0x00,0x00,0x00,0x00},  // intro voice
  46.     { 0x00,0x04,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00},
  47.     { 0x01,0x01,0x40,0x40,0x80,0x80,0x00,0x00,0x01,0x00,0x00},
  48.     { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01},
  49.     { 0xA5,0xB1,0xD2,0x80,0x81,0xF1,0x03,0x05,0x00,0x00,0x02},
  50.     { 0x72,0x62,0x1C,0x05,0x51,0x52,0x03,0x13,0x00,0x00,0x0E},
  51.     { 0x11,0x01,0x8A,0x40,0xF1,0xF1,0x11,0xB3,0x00,0x00,0x06}};
  52.  
  53. int vints[8] = {1,2,1,2,1,2,1,2}; // voice defs for introduction
  54.                                   // Start/end frequencies for intro
  55. WORD startfreq[8] = {0xa000,0x6000,0xa000,0x2000,0x1000,0x9000,0xa000,0x6000};
  56. WORD endfreq[8] =   {0x0800,0x2800,0x4800,0x6800,0x8800,0xa800,0xc800,0xe800};
  57.  
  58. char *regname[11] = {             // register name list
  59.   "Amp mod/ vib/ eg type/ keyscale/ multiple 1",
  60.   "Amp mod/ vib/ eg type/ keyscale/ multiple 2",
  61.   "Key scale level / oper out level 1",
  62.   "Key scale level / oper out level 2",
  63.   "attack/decay rate 1",
  64.   "attack/decay rate 2",
  65.   "sustain level / release rate 1",
  66.   "sustain level / release rate 2",
  67.   "Feedback / Algorythm (oper 1&2)",
  68.   "Wave Form  Select (oper 1)",
  69.   "Wave Form  Select (oper 1)"
  70.   };
  71.  
  72. char hexchar[16] = {"0123456789ABCDEF"};  //  hexidecimal character list
  73. SAMPLE *sound1,*sound2,*aha;
  74. unsigned long int l1=1,l2=1,laha=1;
  75.  
  76. /**************************************************************************
  77.   void main()
  78.  
  79.   DESCRIPTION:   Handles the main menu and sets things up
  80.  
  81. **************************************************************************/
  82. void main()
  83. {
  84.   int i= 0;
  85.   char r = 0,twirl[6]  = "|/-\\";
  86.  
  87.   if(SB_Setup()) {
  88.     Go_Varmint();                            // Install  Varmint's tools
  89.  
  90.     sound1 = loadwave("doink.wav",&l1);     // Load up our sound effects
  91.     sound2 = loadwave("wooeep.wav",&l2);
  92.     aha = loadwave("aha.wav",&laha);
  93.     if(!sound1 || !sound2 || !aha) {
  94.       printf("ERROR loading sounds:  (%d,%d)\n",sound1,sound2);
  95.       exit(0);
  96.     }
  97.  
  98.     sb_intro();                              // Get their attention
  99.  
  100.     while(kbhit()) getch();
  101.     while(r != 'Q') {                       // Main input loop
  102.  
  103.       clrscr();                             // CLear screen and draw menu
  104.       textcolor(DARKGRAY);
  105.       //cprintf("far core left %lu",farcoreleft());
  106.       textcolor(WHITE);
  107.       gotoxy(20,8);
  108.       cprintf("Demonstration:  Varmint's Audio Tools\n\n");
  109.       textcolor(YELLOW);
  110.       gotoxy(30,10);
  111.       cprintf("1) FM voice");
  112.       gotoxy(30,11);
  113.       cprintf("2) MIDI");
  114.       gotoxy(30,12);
  115.       cprintf("3) Sounds");
  116.       gotoxy(30,14);
  117.       cprintf("Q) quit");
  118.  
  119.       while(!kbhit()) {                     // Draw a twirling thing while
  120.                                             // we wait for a keypress.
  121.         gotoxy(35,16);
  122.         cprintf("%c",twirl[++i%4]);
  123.         gotoxy(30,14);
  124.         msdelay(50);
  125.       }
  126.       r = toupper(getch());                 // grab some input
  127.  
  128.       if(r == '1') fmdemo();                // Do something with it
  129.       else if(r == '2') {
  130.         mididemo();
  131.       }
  132.       else if(r == '3') {
  133.         dspdemo();
  134.       }
  135.     }
  136.     Dropdead_Varmint();                     // Release Varmint's interrupt
  137.   }
  138.   else {
  139.     printf("SB_Setup returned this error: %s \n",errname[sberr]);
  140.     printf("(Is your 'BLASTER' environmen variable set up correctly?)\n");
  141.   }
  142.  
  143. }
  144.  
  145. /**************************************************************************
  146.   void dspdemo(void)
  147.  
  148.   DESCRIPTION:  Plays sound effects with Varmint's Audio Tools
  149.  
  150. **************************************************************************/
  151. void dspdemo(void)
  152. {
  153.   char r = 0;
  154.   DWORD tot = 0,num = 0,vc;
  155.  
  156.   DSP_overhead = 1;                           // turn on overhead checking
  157.  
  158.   clrscr();                                   // Clear screen and draw a menu
  159.   textcolor(GREEN);
  160.   gotoxy(25,8);
  161.   cprintf("Sound effects demo menu");
  162.   textcolor(YELLOW);
  163.   gotoxy(25,10);
  164.   cprintf("1,2,3 - Play a sound effect");
  165.   gotoxy(25,11);
  166.   cprintf("Q     - Quit");
  167.  
  168.   gotoxy(1,1);
  169.   printf("CPU OVERHEAD: \nSAMPLES IN QUEUE: ");
  170.   while(toupper(r) != 'Q') {         // input loop
  171.     while(!kbhit()) {                // Wait for keystroke
  172.       vc = vclock;
  173.       while(vc == vclock);           // wait for the interrupt
  174.  
  175.       tot+= DSP_overhead;            // take an average every 40 interrupts
  176.       num++;
  177.       if(num == 40) {
  178.         gotoxy(15,1);
  179.         printf("%2.2lf%%  ",((double)tot/num)/50.0); // Show overhead
  180.         gotoxy(19,2);
  181.         printf("%d  \n",sounds_in_queue);       // Show # sounds playing
  182.         num = 0;
  183.         tot = 0;
  184.       }
  185.     }
  186.     r = getch();                      // Get keystroke and act accordingly
  187.     if(r == '1') playsound(sound1,l1);
  188.     else if(r == '2') playsound(sound2,l2);
  189.     else if(r == '3') playsound(aha,laha);
  190.   }
  191. }
  192.  
  193. /**************************************************************************
  194.   void sb_intro(void)
  195.  
  196.   DESCRIPTION:  Cool introduction sith sound blaster music and sounds
  197.  
  198. **************************************************************************/
  199. void sb_intro(void)
  200. {
  201.   int i,j;
  202.   double fr;
  203.   WORD f;
  204.  
  205.   clrscr();
  206.   gotoxy(1,1);
  207.   printf("Varmint's Audio Tools  (Version: %s)",VAT_VERSION);
  208.   msdelay(500);
  209.  
  210.                                       // Cool introduction
  211.   FM_Reset();
  212.   for(i = 0; i < 2; i++) {
  213.     playsound(aha,laha);              // Digital intro speach
  214.     msdelay(13);
  215.   }
  216.   for(i = 0; i < 8; i++) {             // initialize music voices
  217.     FM_SetVoice(i,inst[vints[i]]);
  218.     FM_SetFreq(i,startfreq[i]);
  219.     FM_SetVol(i,0x00);
  220.     FM_KeyOn(i);
  221.   }
  222.   for(i = 0; i < 1000; i+= 1) {       // morph a big chord
  223.     fr = i/1000.0;
  224.     for(j = 0; j < 8; j++) {
  225.       gotoxy(j*10+1,10);
  226.       f = startfreq[j]+((double)endfreq[j]-(double)startfreq[j]) * fr;
  227.       cprintf("%X  ",f);
  228.       FM_SetFreq(j,f);
  229.       FM_SetVol(j,fr*0x3f );
  230.       FM_KeyOn(j);
  231.     }
  232.     msdelay(5);
  233.     if(kbhit()) i = 1000;
  234.   }
  235.  
  236.   if(!kbhit()) {
  237.     for(i = 0; i < 8; i++) {          // Make sure all the notes are right
  238.       FM_SetFreq(i,endfreq[i]);
  239.       FM_KeyOn(i);
  240.     }
  241.  
  242.     for(i = 0x3f ; i >= 0; i-= 1) {   // quiet down slowly
  243.       for(j = 0; j < 8; j++) {
  244.         FM_SetVol(j,i);
  245.       }
  246.       msdelay(i*2+40);
  247.       if(kbhit() & i) i = 1;
  248.     }
  249.   }
  250.  
  251.   for(i = 0; i < 9; i++) {            // Silence them all
  252.     FM_SetVol(i,0);                   // volume off
  253.     FM_SetVoice(i,inst[0]);           // this instrument has a decay, so it
  254.                                       // gets all the way quiet
  255.     FM_SetFreq(i,1);                  // Low freq = quiet
  256.   }
  257.  
  258. }
  259. /**************************************************************************
  260.   void mididemo(void)
  261.  
  262.   DESCRIPTION: Example function that loads and "plays" a  midi file
  263.  
  264. **************************************************************************/
  265. void mididemo(void)
  266. {
  267.   int i,err;
  268.   char *errstring[256],r=0;
  269.   static MIDI *bach  = NULL;
  270.  
  271.   clrscr();                                    // clear screen
  272.   FM_Reset();
  273.  
  274.   for(i = 0 ; i < 9; i++) {
  275.     FM_SetVol(i,0);
  276.     FM_SetVoice ( i,inst[0]) ;                 // initialize voice
  277.   }
  278.   if(!bach) {
  279.                                               // load a midi file
  280.     err = ReadMidi("bach.mid",&bach,(char *)errstring);
  281.     if(err) {
  282.       printf("MIDI read ERROR: %s\n",errstring);
  283.       printf("Exit?\n");
  284.       r = getch();
  285.       if(r != 'n') return;
  286.     }
  287.   }
  288.  
  289.   //printf("FORMAT:  %d  TRACKS: %d   DIVISION: %d\n",
  290.   //        bach->format,bach->num_tracks,bach->divisions);
  291.  
  292.   midi_data = bach;
  293.   midi_reset = TRUE;
  294.  
  295.   textcolor(MAGENTA);
  296.   gotoxy(25,2);
  297.   cprintf("MIDI demo menu");                 // Draw the menu
  298.   textcolor(CYAN);
  299.   gotoxy(25,4);
  300.   cprintf("V,v - Change music volume");
  301.   gotoxy(25,5);
  302.   cprintf("T,t - Change music tempo");
  303.   gotoxy(25,6);
  304.   cprintf("B   - Begin music");
  305.   gotoxy(25,7);
  306.   cprintf("S   - Stop Music");
  307.   gotoxy(25,8);
  308.   cprintf("R   - Reset midi");
  309.   gotoxy(25,9);
  310.   cprintf("Q   - Quit");
  311.  
  312.  
  313.   while(toupper(r) != 'Q') {
  314.     gotoxy(30,11);                            // print temppo and volume stats
  315.     textcolor(WHITE);
  316.     cprintf("Music Volume: %d  ",music_volume);
  317.     gotoxy(30,12);
  318.     cprintf("Music Tempo:  %.2f  ",midi_usertempo);
  319.  
  320.     while(!kbhit()) {
  321.       gotoxy(1,1);
  322.       //printf("D: %d",debugnum);
  323.     }
  324.     r = getch();                              // get keystroke
  325.  
  326.     if(r == 'V') {
  327.       music_volume++;
  328.       if(music_volume > 0x3f) music_volume = 0x3f;
  329.     }
  330.     else if(r == 'v') {
  331.       if(music_volume > 0) music_volume--;
  332.     }
  333.     else if(r == 'T') {
  334.       midi_usertempo *= 1.02;
  335.       if(midi_usertempo > 10.0) midi_usertempo = 10.0;
  336.     }
  337.     else if(r == 't') {
  338.       midi_usertempo *= 0.98;
  339.       if(midi_usertempo < 0.1) midi_usertempo = 0.1;
  340.     }
  341.     else if(toupper(r) == 'B') {
  342.       midi_on = TRUE;
  343.     }
  344.     else if(toupper(r) == 'S') {
  345.       midi_on = FALSE;
  346.     }
  347.     else if(toupper(r) == 'R') {
  348.       midi_reset = TRUE;
  349.     }
  350.   }
  351. }
  352.  
  353.  
  354. /**************************************************************************
  355.   void bitprint(char byte)
  356.  
  357.   DESCRIPTION:  Prints individual bits and then a HEX value
  358.  
  359. **************************************************************************/
  360. void bitprint(unsigned char byte)
  361. {
  362.   int i;
  363.  
  364.   cprintf("  ");
  365.                                     // go through bits
  366.   for(i = 7; i >= 0; i--) {
  367.     if(getbit(byte,i)) {            // 1's are yellow
  368.       textcolor(YELLOW);
  369.       cprintf("1");
  370.     }
  371.     else {                          // 0's are dark grey
  372.       textcolor(DARKGRAY);
  373.       cprintf("0");
  374.     }
  375.   }
  376.  
  377.   textcolor(LIGHTBLUE);             // print the hex value
  378.   cprintf("  %c%c",hexchar[byte/16],hexchar[byte%16]);
  379.   textcolor(WHITE);
  380. }
  381.  
  382.  
  383.  
  384. /**************************************************************************
  385.   void fmdemo()
  386.  
  387.   DESCRIPTION:  Allows th user to mess around with instruments and
  388.                 play a few notes.
  389.  
  390.  
  391. **************************************************************************/
  392. void fmdemo(void)
  393. {
  394.   unsigned int i,cx,cy,voice=0,instrument = 0;
  395.   int drawvoice = 1,rythm = 0;
  396.   char r = 0;
  397.  
  398.   clrscr();                          // clear screen
  399.   printf("FM demonstration screen");
  400.   FM_Reset();
  401.   for(i = 0; i < 9; i++) FM_KeyOff(i);
  402.  
  403.   gotoxy(1,16);
  404.   cprintf("IJKL = cursor movement\r\n");
  405.   cprintf("<space> = toggle bit\r\n");
  406.   cprintf("numbers = play notes\r\n");
  407.   cprintf("v = change voice\r\n");
  408.   cprintf("n = Change instrument\r\n");
  409.   cprintf("r = toggle rythm mode\r\n");
  410.   cprintf("q = quit");
  411.  
  412.   _setcursortype(_SOLIDCURSOR);
  413.   for( i = 0; i < 8; i++) {          // initialize voices
  414.     FM_SetVoice ( i,inst[instrument]) ;
  415.     FM_SetVol(i,0);
  416.   }
  417.  
  418.   cx = 54;cy = 5;                    // init cursor position
  419.  
  420.   for(i = 0; i < 11; i++) {          // print register names
  421.     gotoxy(50-strlen(regname[i]),i+5);
  422.     textcolor(MAGENTA);
  423.     cprintf("%s",regname[i]);
  424.   }
  425.  
  426.  
  427.   while(r != 'Q') {                  // main input loop
  428.     if(drawvoice) {
  429.       for(i = 0; i < 11; i++) {      // display instrument data
  430.         gotoxy(52,i+5);
  431.         bitprint(inst[instrument][i]);
  432.       }
  433.       for(i = 0; i < 9; i++) {
  434.         FM_SetVoice ( i,inst[instrument]) ; // initialize new voice
  435.       }
  436.       drawvoice = 0;
  437.       textcolor(LIGHTGRAY);
  438.       gotoxy(52,4);
  439.       cprintf("Instrument #%d ",instrument);
  440.     }
  441.  
  442.     gotoxy(cx,cy);                   // put cursor in right spot
  443.  
  444.     while(!kbhit()){
  445.     }
  446.  
  447.     r = toupper(getch());
  448.     if(r >= '0' && r <= '9') {
  449.       FM_KeyOff(voice);
  450.       FM_SetVoice(voice,inst[instrument]);
  451.       FM_SetNote ( voice, (r-'0'+3) * 8) ;
  452.       FM_SetVol(voice,music_volume);
  453.       FM_KeyOn(voice);
  454.     }
  455.     else if(r == 'I') {              // i,j,k,l = cursor movement
  456.       cy = cy -1;
  457.       if(cy<5) cy = 5;
  458.     }
  459.     else if(r == 'K') {
  460.       cy = cy +1;
  461.       if(cy >15) cy = 15;
  462.     }
  463.     else if(r == 'J') {
  464.       cx = cx -1;
  465.       if(cx<54) cx = 54;
  466.     }
  467.     else if(r == 'L') {
  468.       cx = cx +1;
  469.       if(cx>61) cx = 61;
  470.     }
  471.     else if(r == ' ') {              // space = toggle bit
  472.       togbit(inst[instrument][cy-5],(7-(cx-54)));
  473.       drawvoice = 1;
  474.     }
  475.     else if(r == 'N') {               // I = change instrument
  476.       instrument++;
  477.       if(instrument > 8) instrument = 0;
  478.       drawvoice = 1;
  479.     }
  480.     else if(r == 'R') {              // r = toggle rythm mode
  481.       if(rythm) rythm = 0;
  482.       else rythm = 1;
  483.       FM_RythmMode(rythm);           // do it
  484.       FM_RythmOn(FM_HIHAT);
  485.       gotoxy(1,2);                   // tell the user
  486.       if(rythm) cprintf("Rythm Mode ON  (voices 6,7,8 only) ");
  487.       else       cprintf("Rythm Mode OFF                     ");
  488.     }
  489.     else if(r == 'V') {              //  v = change voice
  490.       FM_KeyOff(voice);
  491.       FM_SetVol(voice,0);
  492.       voice ++;
  493.       if(voice > 8) voice = 0;
  494.       gotoxy(1,3);
  495.       cprintf("Voice: %d ",voice);
  496.     }
  497.     else if(r == 'W') {              // Frequency ramp
  498.       for(i = 0; i < 0xf000; i+= 0x10) {
  499.         FM_SetFreq(voice,i);
  500.         FM_KeyOn(voice);
  501.         msdelay(5);
  502.       }
  503.     }
  504.  
  505.  
  506.   }
  507.   for(i = 0; i < 9; i++) {
  508.     FM_SetVol(i,0);
  509.   }
  510.  
  511. }
  512.  
  513.  
  514.  
  515.  
  516.